package com.kanbox.api;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;

import org.apache.http.client.methods.HttpRequestBase;
import org.json.JSONException;
import org.json.JSONObject;


import android.util.Log;

import com.kanbox.api.KanboxServer.KanboxHttp;

public class Token {
    private String acceccToken;
    private String refreshToken;
    private long expires;
    private static Token mToken;

    private Token() {
    }

    public static final Token getInstance() {
        if (mToken == null) {
            mToken = new Token();
        }
        return mToken;
    }

    /**
     *
     *
     * @param response
     * @throws JSONException
     */
    public void parseToken(String response) throws JSONException {
        JSONObject sData = new JSONObject(response);
        acceccToken = sData.getString("access_token");
        expires = sData.getLong("expires_in");
        refreshToken = sData.getString("refresh_token");
    }


    public void setToken(String acceccToken, String refreshToken, long expires) {
        this.acceccToken = acceccToken;
        this.refreshToken = refreshToken;
        this.expires = expires;
    }

    /**
     *
     *
     * @param clientId
     * @param clientSecret
     * @param code
     * @param redirectUrl
     * @param listener
     * @throws UnsupportedEncodingException
     */
    public void getToken(String clientId, String clientSecret, String code,
            String redirectUrl, RequestListener listener)
            throws UnsupportedEncodingException {
        String getTokenUrl = "https://auth.kanbox.com/0/token";
        if(Kanbox.TEST){
            getTokenUrl = "http://auth.kanbox.com/0/token";
        }
        HashMap<String, String> params = new HashMap<String, String>();
        params.put("grant_type", "authorization_code");
        params.put("client_id", clientId);
        params.put("client_secret", clientSecret);
        params.put("code", code);
        params.put("redirect_uri", redirectUrl);

        HttpRequestBase httpMethod = KanboxHttp.doPost(getTokenUrl, params);
        KanboxServer.getInstance().doHttp(httpMethod, listener, Constant.OP_GET_TOKEN);
    }
    /**
     *
     *
     * @param clientId
     * @param clientSecret
     * @param code
     * @param redirectUrl
     * @param listener
     * @throws UnsupportedEncodingException
     */
    public void getTokenByHavana(String clientId, String clientSecret, String havanaID,
            String redirectUrl, RequestListener listener)
            throws UnsupportedEncodingException {
        String getTokenUrl = "https://auth.kanbox.com/0/token";
        if(Kanbox.TEST){
            getTokenUrl = "http://auth.kanbox.com/1/token";
        }
        String md5;

        long timestamp = System.currentTimeMillis()/1000;
        //Log.e("FileListFragmentToken", "clientId "+clientId+",havandID is "+havanaID+",timeStamp is "+timestamp+",clientSecret is "+clientSecret);
        String src = "havana" + clientId + havanaID + timestamp+ clientSecret;
        //Log.e("FileListFragmentToken","src is "+src+"timestamp is "+Long.toString(timestamp));
        md5 = getMD5(src);
        //Log.e("FileListFragmentToken", "getTokenByHavana md5 is "+md5+"\n time is "+timestamp);
        HashMap<String, String> params = new HashMap<String, String>();
        params.put("grant_type", "havana");
        params.put("client_id", clientId);
        params.put("havana_id", havanaID);
        params.put("time_stamp",Long.toString(timestamp));
        params.put("md5", md5);
        //Log.e("FileListFragmentToken","getTokenByHavana url is "+getTokenUrl);
        HttpRequestBase httpMethod = KanboxHttp.doPost(getTokenUrl, params);
        KanboxServer.getInstance().doHttp(httpMethod, listener, Constant.OP_GET_TOKEN);
    }

    public static String getMD5(String string) {
        byte[] hash;
        try {
            hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Huh, MD5 should be supported?", e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("Huh, UTF-8 should be supported?", e);
        }
        StringBuilder hex = new StringBuilder(hash.length * 2);
        for (byte b : hash) {
            if ((b & 0xFF) < 0x10) hex.append("0");
            hex.append(Integer.toHexString(b & 0xFF));
        }
        return hex.toString();
    }

    /**
     *
     *
     * @param clientId
     * @param clientSecret
     * @param listener
     * @throws UnsupportedEncodingException
     */
    public void refreshToken(String clientId, String clientSecret,
            RequestListener listener) throws UnsupportedEncodingException {
        String refreshTokenUrl = "https://auth.kanbox.com/0/token";
         if(Kanbox.TEST){
             refreshTokenUrl = "http://auth.kanbox.com/0/token";
            }
        HashMap<String, String> params = new HashMap<String, String>();
        params.put("grant_type", "refresh_token");
        params.put("client_id", clientId);
        params.put("client_secret", clientSecret);
        params.put("refresh_token", refreshToken);

        HttpRequestBase httpMethod = KanboxHttp.doPost(refreshTokenUrl, params);
        KanboxServer.getInstance().doHttp(httpMethod, listener, Constant.OP_REFRESH_TOKEN);
    }

    public String getAcceccToken() {
        return acceccToken;
    }

    public void setAcceccToken(String acceccToken) {
        this.acceccToken = acceccToken;
    }

    public String getRefreshToken() {
        return refreshToken;
    }

    public void setRefreshToken(String refreshToken) {
        this.refreshToken = refreshToken;
    }

    public long getExpires() {
        return expires;
    }

    public void setExpires(long expires) {
        this.expires = expires;
    }

}
